package com.cloudfun.campusshare.service.impl;

import com.cloudfun.campusshare.common.model.vo.AuthoritySimpleListVO;
import com.cloudfun.campusshare.common.security.AuthenticationHolder;
import com.cloudfun.campusshare.entity.AuthorityEntity;
import com.cloudfun.campusshare.entity.RoleAuthorityRel;
import com.cloudfun.campusshare.repo.AuthorityEntityRepo;
import com.cloudfun.campusshare.repo.RoleAuthorityRelRepo;
import com.cloudfun.campusshare.service.AuthorityService;
import com.cloudfun.campusshare.service.RoleService;
import com.cloudfun.campusshare.util.BeanCopyUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * Created by Huqin on 2020/5/13
 */
@Slf4j
@Service
public class AuthorityServiceImpl implements AuthorityService {

    @Autowired
    private AuthorityEntityRepo authorityEntityRepo;

    @Autowired
    private RoleAuthorityRelRepo roleAuthorityRelRepo;

    @Autowired
    private RoleService roleService;

    @Override
    public List<AuthoritySimpleListVO> getSimpleList() {
        List<AuthorityEntity> authorityEntities;
        if (AuthenticationHolder.isAdmin()) {
            authorityEntities = authorityEntityRepo.findAll();
        } else {
            authorityEntities = this.getUserAuthorities(AuthenticationHolder.getUserId());
        }
        List<AuthoritySimpleListVO> simpleListVOList = authorityEntities.stream()
                .sorted(Comparator.comparingInt(AuthorityEntity::getSeq))
                .map(entity -> {
                    AuthoritySimpleListVO res = BeanCopyUtil.copy(entity, AuthoritySimpleListVO.class);
                    res.setKey(entity.getId());
                    res.setTitle(entity.getCnName());
                    return res;
                }).collect(Collectors.toList());
        Map<String, List<AuthoritySimpleListVO>> parentIdChildrenMap = simpleListVOList.stream().collect(Collectors.groupingBy(AuthoritySimpleListVO::getParentId));
        List<AuthoritySimpleListVO> res = new ArrayList<>();
        for (AuthoritySimpleListVO authoritySimpleListVO : simpleListVOList) {
            authoritySimpleListVO.setChildren(parentIdChildrenMap.get(authoritySimpleListVO.getId()));
            if (authoritySimpleListVO.getParentId().equals(ROOT_ID)) {
                res.add(authoritySimpleListVO);
            }
        }
        return res;
    }

    @Override
    public List<AuthorityEntity> getAuthorities(Collection<String> roleIds) {
        if (CollectionUtils.isEmpty(roleIds)) {
            return new ArrayList<>();
        }
        List<RoleAuthorityRel> allByRoleId = roleAuthorityRelRepo.findAllByRoleIdIn(roleIds);
        List<String> authIds = allByRoleId.stream().map(RoleAuthorityRel::getAuthorityId).collect(Collectors.toList());
        return authorityEntityRepo.findAllByIdIn(authIds);
    }

    @Override
    public List<AuthorityEntity> getUserAuthorities(String userId) {
        Set<String> roleIds = roleService.getRoleIds(userId);
        return this.getAuthorities(roleIds);
    }

    @Override
    public List<AuthorityEntity> getAuthorities(String roleId) {
        if (StringUtils.isBlank(roleId)) {
            return new ArrayList<>();
        }
        List<RoleAuthorityRel> allByRoleId = roleAuthorityRelRepo.findAllByRoleId(roleId);
        List<String> authIds = allByRoleId.stream().map(RoleAuthorityRel::getAuthorityId).collect(Collectors.toList());
        return authorityEntityRepo.findAllByIdIn(authIds);
    }

}
